package atom.core1.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import atom.core0.util.MapUtil;
import atom.core0.util.StringUtil;

public class Map2BeanUtil {
	private static final Logger logger = Logger.getLogger(Map2BeanUtil.class);

	// bean内字段 不能是其他bean
	// public static void transMap2Bean(Map<String, Object> map, Object obj)
	// throws Exception {
	// BeanUtils.populate(obj, map);
	// }

	// bean内字段 不能是其他bean oldkey->beanfield
	// public static void transMap2Bean(Map<String, Object> map, Object obj,
	// Map<String, String> rulermap) throws Exception {
	//
	// if (rulermap == null) {
	// BeanUtils.populate(obj, map);
	// return;
	// }
	// Map newmap = new HashMap<String, Object>();
	// // 对map中的值，按照rulermap 转换key
	// Iterator it = map.entrySet().iterator();
	// while (it.hasNext()) {
	// Map.Entry entry = (Map.Entry) it.next();
	// String key = (String) entry.getKey();
	// Object value = entry.getValue();
	//
	// // 查找rulermap 用新的key 代替
	// String newkey = rulermap.get(key);
	// if (StringUtil.isEmpty(newkey))
	// newkey = key;
	//
	// // System.out.println(newkey+"==="+value);
	// newmap.put(newkey, value);
	// }
	// BeanUtils.populate(obj, newmap);
	// }

	// 批量转换时，以第一个map为模版,记录下来映射关系，以后就直接用map查找，会快
	public static List transListMap2ListBeanIgnoreCase(List<Map<String, Object>> listmap, Class objectclass, Map<String, String> rulermap) throws Exception {
		if (listmap.size() <= 0)
			return null;
		
		//如果rulermap为空，则自动生成rulermap
		if (rulermap==null)
			rulermap = getRulerMapIgnoreCase(listmap.get(0), objectclass);
		
		List<Object> listobject = new ArrayList();
		for (int i = 0; i < listmap.size(); i++) {
			Object obj = transMap2BeanIgnoreCase(listmap.get(i), objectclass, rulermap);
			listobject.add(obj);
		}
		return listobject;
	}

	// 数据库字段会去掉下划线 然后跟bean比较 不区分大小写
	public static Object transMap2BeanIgnoreCase(Map<String, Object> map, Class objectclass, Map<String, String> rulermap) throws Exception {

		Method[] methods = objectclass.getDeclaredMethods();
		Object obj = objectclass.newInstance();
		for (Method method : methods) {
			if (method.getName().contains("set")) {
				if (method.getParameterTypes().length == 1) {
					// 基础类型 直接调用
					if (method.getParameterTypes()[0].getClassLoader() == null) {
						String beanfield = getMethodFieldName(method.getName());

						Object value;
						if (rulermap != null) {
							String oldkey = rulermap.get(beanfield);
							if (StringUtil.isEmpty(oldkey))
								oldkey = beanfield;
							value = map.get(oldkey);
						} else {
							value = MapUtil.getMapValueIgnoreCase(map, beanfield);
						}

						if (value != null) {
							// value如果是Integer或者Long，可能会转换错误
							Object newvalue = convertType(method.getParameterTypes()[0], value);
							method.invoke(obj, new Object[] { newvalue });
						}
					}
					// 复合类型
					else {
						Object value = transMap2BaseBeanIgnoreCase(map, method.getParameterTypes()[0],rulermap);
						if (value != null)
							method.invoke(obj, new Object[] { value });
					}
				}
			}
		}
		return obj;
	}


	// 只转换基础类型
	private static Object transMap2BaseBeanIgnoreCase(Map<String, Object> map, Class objectclass,Map<String, String> rulermap) throws Exception {

		Method[] methods = objectclass.getDeclaredMethods();
		Object obj = objectclass.newInstance();
		for (Method method : methods) {
			if (method.getName().contains("set")) {
				if (method.getParameterTypes().length == 1) {
					// 基础类型 直接调用
					if (method.getParameterTypes()[0].getClassLoader() == null) {
						String beanfield = getMethodFieldName(method.getName());
						Object value;
						if (rulermap != null) {
							String oldkey = rulermap.get(beanfield);
							if (StringUtil.isEmpty(oldkey))
								oldkey = beanfield;
							value = map.get(oldkey);
						}
						else
							value = MapUtil.getMapValueIgnoreCase(map, beanfield);
						
						if (value != null) {

							// value如果是Integer或者Long，可能会转换错误
							Object newvalue = convertType(method.getParameterTypes()[0], value);
							method.invoke(obj, new Object[] { newvalue });
						}
					}
				}
			}
		}
		return obj;

	}

	// setUsers() 去掉 set 和() 首字母小写
	private static String getMethodFieldName(String methodName) {
		
		String fieldname = methodName.substring(3,4).toLowerCase()+methodName.substring(4);
		return fieldname;
	}

	private static Object convertType(Class fieldclass, Object value) {
		if (fieldclass.getName().equals("java.lang.Long")) {
			Long result = Long.valueOf(String.valueOf(value));
			return result;
		} else if (fieldclass.getName().equals("java.lang.Integer")) {
			Integer result = Integer.valueOf(String.valueOf(value));
			return result;
		} else if (fieldclass.getName().equals("java.lang.Double")) {
			Double result = Double.valueOf(String.valueOf(value));
			return result;
		}
		
		else if (fieldclass.getName().equals("java.math.BigDecimal")) {
			BigDecimal result = new BigDecimal(String.valueOf(value));
			return result;
		}	
		//Character
		else if (fieldclass.getName().equals("java.lang.String")) {
			return String.valueOf(value);
		}		
		return value;
	}

	// Map的key(数据库字段)会去掉下划线 然后跟beanfield比较,而且 不区分大小写
	// 当有复合bean类似主键时，只深入一层

	// 注意key是beanfield value是oldkey
	// beanfield->oldkey
	public static Map<String, String> getRulerMapIgnoreCase(Map<String, Object> map, Class objectclass) {
		//不能以 Field[] fields为准 因为可能 field 是 FName(数据库自动生成) 函数是 setFName
		//所以，首字母如果是大写，映射要修改成小写
		Map<String, String> rulermap = new HashMap<String, String>();
		List<Class> classlist = new ArrayList();
		try {
			Field[] fields = objectclass.getDeclaredFields();
			for (Field f : fields) {
				// beanfield是bean的字段 要不能含下划线
				String beanfield = f.getName();
				String newbeanfield = beanfield.substring(0,1).toLowerCase()+beanfield.substring(1);
				
				if (f.getType().getClassLoader() != null) {
					// 不是java原生类型
					classlist.add(f.getType());
					continue;
				}
				// 相似也注入
				String oldkey = MapUtil.getMapKeyIgnoreCase(map, newbeanfield);
				if (oldkey != null) {
					rulermap.put(newbeanfield, oldkey);
				}

			}

			// 处理类似复合主键的
			for (int i = 0; i < classlist.size(); i++) {
				Class keyclass = classlist.get(i);
				
				//Method[] keymethods = objectclass.getDeclaredMethods();
				Field[] keyfields = keyclass.getDeclaredFields();

				for (Field f : keyfields) {
					// beanfield是bean的字段 要不能含下划线
					String beanfield1 = f.getName();
					String newbeanfield = beanfield1.substring(0,1).toLowerCase()+beanfield1.substring(1);
					// 相似也注入
					String oldkey = MapUtil.getMapKeyIgnoreCase(map, newbeanfield);
					if (oldkey != null) {
						rulermap.put(newbeanfield, oldkey);
					}

				}

			}

		} catch (Exception e) {
			logger.error("getRulerMapIgnoreCase error" + e.getMessage(), e);
		}

		return rulermap;
	}
}
